
#include "pulsar.h"

#if defined(__GNUC__) || defined(__MINGW__) || defined(__MINGW32__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wconversion"
#endif


namespace Den
{
    namespace
    {
        typedef Pulse::EventWakeUp      
            EventWakeUp;
        typedef Pulse::MicroSeconds    
            MicroSeconds;
        typedef Pulse::Seconds          
            Seconds;

    }//namespace

    Pulse::Pulse()
        :mDelay(0)
        ,mElapsed(0)
        ,mEvent( EventWakeUp() )
    {}

    Pulse::Pulse( const Seconds delay, const EventWakeUp& wakeup)
        :mDelay(   static_cast<MicroSeconds>(1000000*delay)   )
        ,mElapsed(0)
        ,mEvent(wakeup)
    {}
    Pulse::Pulse( const MicroSeconds delay, const EventWakeUp& wakeup)
        :mDelay(delay)
        ,mElapsed(0)
        ,mEvent(wakeup)
    {}

    void Pulse::Restart(const Seconds delay, const EventWakeUp& wakeup)
    {
        mDelay = static_cast<MicroSeconds>(delay*1000000);
        mEvent = wakeup;
        mElapsed=0;
    }
    void Pulse::Restart(const MicroSeconds delay, const EventWakeUp& wakeup)
    {
        mDelay = delay;
        mEvent = wakeup;
        mElapsed=0;
    }

    void Pulse::Stop()
    {
        mDelay   = 0;
        mElapsed = 0;
        mEvent   = EventWakeUp();
    }
    void Pulse::Start()
    {
        mElapsed=0; 
    }
    void Pulse::Start(const Seconds delay)
    {
        mElapsed=0; 
        mDelay = static_cast<MicroSeconds>(1000000*delay);
    }
    void Pulse::Start(const MicroSeconds delay)
    {
        mElapsed=0; 
        mDelay = delay; 
    }

    MicroSeconds Pulse::ElapsedMS()const { return mElapsed; }
    Seconds Pulse::ElapsedS()const       { return  static_cast<Seconds>(mElapsed/1000000.0); }

    MicroSeconds Pulse::RemainingMS()const
    {
        const auto elapsed = ElapsedMS(); 
        return (mDelay<=elapsed)? 0: mDelay-elapsed;
    }
    Seconds Pulse::RemainingS()const { return static_cast<Seconds>(RemainingMS()/1000000.0);  }

    bool Pulse::TickTock(const MicroSeconds& msec)
    {
        if(mDelay == 0)
            return false;
        mElapsed += msec;
        if(RemainingMS()!=0)
            return true;
        if(mEvent && mEvent())
            Start();
        return false;
    }

    bool Pulse::TickTock(const Seconds& sec) { return TickTock( static_cast<MicroSeconds>(1000000*sec) ); }

} // namespace Den

#if defined(__GNUC__) || defined(__MINGW__) || defined(__MINGW32__)
    #pragma GCC diagnostic pop
#endif
